# ***********************************************************
# |docname| - Configuration file for BookServer documentation
# ***********************************************************
# To build the documentation, execute ``sphinx-build . _build`` from the project's root directory. For a GUI alternative, this project is configured for the `CodeChat system <https://codechat-system.readthedocs.io/en/latest/>`_.
#
# Introduction
# ============
# This file configures Sphinx, which transforms restructured text (reST) into
# html. See Sphinx `build configuration file docs
# <http://sphinx-doc.org/config.html>`_ for more information on the settings
# below.
#
# This file was originally created by sphinx-quickstart, then modified by hand.
# Notes on its operation:
#
# * This file is ``execfile()``\d by Sphinx with the current directory set to
#   its containing dir.
# * Not all possible configuration values are present in this autogenerated
#   file.
# * All configuration values have a default; values that are commented out serve
#   to show the default.
#
#
# Imports
# =======
# These are listed in the order prescribed by `PEP 8`_.
#
# Standard library
# ----------------
from pathlib import Path

#
# Third-party imports
# -------------------
import CodeChat.CodeToRest
from sphinx.application import Sphinx
from sphinx.config import Config

# Local application imports
# -------------------------
# None.
#
# Path additions
# --------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, as shown here.
##sys.path.insert(0, os.path.abspath('.'))
#
# `Project information <http://sphinx-doc.org/config.html#project-information>`_
# ==============================================================================
# `project <http://sphinx-doc.org/config.html#confval-project>`_  and
# `copyright <http://sphinx-doc.org/config.html#confval-copyright>`_:
# General information about the project. **Change this** for your project.
project = "Runestone BookServer"
copyright = "2020, 2021, Runestone Interactive LLC"

# The version info for the project you're documenting, acts as replacement for
# ``|version|`` and ``|release|``, also used in various other places throughout
# the built documents. **Change these** for your project.
#
# `version <http://sphinx-doc.org/config.html#confval-version>`_: The short X.Y
# version.
version = "0.1"
# `release <http://sphinx-doc.org/config.html#confval-release>`_: The full
# version, including alpha/beta/rc tags.
release = "version 0.0"

# There are two options for replacing ``|today|``:
#
# \1. If you set `today <http://sphinx-doc.org/config.html#confval-today>`_ to
# some non-false value, then it is used:
##today = ''
# \2. Otherwise, `today_fmt <http://sphinx-doc.org/config.html#confval-today_fmt>`_
# is used as the format for a strftime call.
##today_fmt = '%B %d, %Y'

# `highlight_language <http://sphinx-doc.org/config.html#confval-highlight_language>`_:
# The default language to highlight source code in.
highlight_language = "python"

# `pygments_style <http://sphinx-doc.org/config.html#confval-pygments_style>`_:
# The style name to use for Pygments highlighting of source code.
pygments_style = "sphinx"

# `add_function_parentheses <http://sphinx-doc.org/config.html#confval-add_function_parentheses>`_:
# If true, '()' will be appended to ``:func:`` etc. cross-reference text.
##add_function_parentheses = True

# `add_module_names <http://sphinx-doc.org/config.html#confval-add_module_names>`_:
# If true, the current module name will be prepended to all description unit
# titles (such as ``.. function::``).
##add_module_names = True

# `show_authors <http://sphinx-doc.org/config.html#confval-show_authors>`_: If
# true, ``sectionauthor`` and ``moduleauthor`` directives will be shown in the
# output. They are ignored by default.
##show_authors = False

# `modindex_common_prefix <http://sphinx-doc.org/config.html#confval-modindex_common_prefix>`_:
# A list of ignored prefixes for module index sorting.
##modindex_common_prefix = []

#
# `General configuration <http://sphinx-doc.org/config.html#general-configuration>`_
# ==================================================================================
# `extensions <http://sphinx-doc.org/config.html#confval-extensions>`_: If your
# documentation needs a minimal Sphinx version, state it here.
##needs_sphinx = '1.5'

# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. **CodeChat
# note:** The ``CodeChat.CodeToRestSphinx`` extension is mandatory; without it,
# CodeChat will not translate source code to reST and then (via Sphinx) to html.
extensions = ["CodeChat.CodeToRestSphinx", "sphinx.ext.intersphinx", "sphinx_rtd_theme"]

# `templates_path <http://sphinx-doc.org/config.html#confval-templates_path>`_:
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]

# `rst_epilog <http://www.sphinx-doc.org/en/stable/config.html#confval-rst_epilog>`_:
# A string of reStructuredText that will be included at the end of every source
# file that is read.
rst_epilog = (
    # Provide a convenient way to refer to a source file's name.
    """

.. |docname| replace:: :docname:`name`
"""
    # A commonly-used link.
    """
.. _PEP 8: http://www.python.org/dev/peps/pep-0008/#imports
"""
)

# `source_suffix <http://sphinx-doc.org/config.html#confval-source_suffix>`_:
# The suffix of source filenames.
source_suffix = ".rst"

# **CodeChat note:** _`CodeChat_lexer_for_glob` is a dict of {glob_,
# lexer_alias}, which uses lexer_alias (e.g. a lexer's `short name
# <http://pygments.org/docs/lexers/>`_) to analyze any file which matches the
# given glob-style pattern (e.g. `glob
# <https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.match>`_).
CodeChat_lexer_for_glob = {
    # These files also use ``#`` for comments, but the non-comments aren't valid Python. Call these an INI file instead.
    "nginx.conf": "INI",
    ".gitignore": "INI",
    ".flake8": "INI",
    "requirements-rtd.txt": "INI",
    ".coveragerc": "INI",
}

# `source_encoding <http://sphinx-doc.org/config.html#confval-source_encoding>`_:
# The encoding of source files.
##source_encoding = 'utf-8-sig'

# `master_doc <http://sphinx-doc.org/config.html#confval-master_doc>`_: The
# master toctree document.
master_doc = "index"

# `language <http://sphinx-doc.org/config.html#confval-language>`_:
# The language for content autogenerated by Sphinx. Refer to documentation for a
# list of supported languages.
##language = None

# `exclude_patterns <http://sphinx-doc.org/config.html#confval-exclude_patterns>`_:
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
#
# **Important:** Do **NOT** add ``CodeChat.css`` to this list; this will
# instruct Sphinx not to copy it to the ``_static`` directory, where it
# is needed to properly lay out CodeChat output.
exclude_patterns = [
    # Misc files.
    "Thumbs.db",
    ".DS_Store",
    # Files excluded for obvious reasons.
    "**/.pytest_cache",
    ".pytest_cache",
    "**/.mypy_cache",
    ".mypy_cache",
    "poetry.lock",
    ".tox",
    ".venv",
    # **CodeChat notes:**
    #
    # By default, Enki will instruct Sphinx to place all Sphinx output in
    # ``_build``; this directory should therefore be excluded from the list of
    # source files.
    "_build",
    # The ``CodeToRestSphinx`` extension creates a file named
    # ``sphinx-enki-info.txt``, which should be ignored by Sphinx.
    "sphinx-enki-info.txt",
    # This is produced by the coverage run in the test suite; see `.coveragerc`.
    "test/htmlcov",
]

# `default_role <http://sphinx-doc.org/config.html#confval-default_role>`_: The
# reST default role (used for this markup: ```text```) to use for all documents.
default_role = "any"

# `keep_warnings <http://sphinx-doc.org/config.html#confval-keep_warnings>`_: If
# true, keep warnings as "system message" paragraphs in the built documents.
# Regardless of this setting, warnings are always written to the standard error
# stream when sphinx-build is run. **CodeChat note**: This should always be
# True; doing so places warnings next to the offending text in the web view,
# making them easy to find and fix.
keep_warnings = True
#
# `Options for HTML output <http://sphinx-doc.org/config.html#options-for-html-output>`_
# ======================================================================================
# `html_theme <http://sphinx-doc.org/config.html#confval-html_theme>`_: The
# theme to use for HTML and HTML Help pages.
html_theme = "sphinx_rtd_theme"

# `html_theme_options <http://sphinx-doc.org/config.html#confval-html_theme_options>`_:
# Theme options are theme-specific and customize the look and feel of a theme
# further. For `Read the docs <https://sphinx-rtd-theme.readthedocs.io/en/latest/configuring.html>`_

html_theme_options = {
    "collapse_navigation": True,
    "sticky_navigation": True,
    "titles_only": True,
}

# `html_style <http://sphinx-doc.org/config.html#confval-html_style>`_: The
# style sheet to use for HTML pages.
##html_style = None

# `html_theme_path <http://sphinx-doc.org/config.html#confval-html_theme_path>`_:
# Add any paths that contain custom themes here, relative to this directory.
##html_theme_path = []

# `html_title <http://sphinx-doc.org/config.html#confval-html_title>`_: The
# name for this set of Sphinx documents.  If None, it defaults to ``<project>
# v<release> documentation``.
##html_title = None

# `html_short_title <http://sphinx-doc.org/config.html#confval-html_short_title>`_:
# A shorter title for the navigation bar.  Default is the same as html_title.
##html_short_title = None

# `html_logo <http://sphinx-doc.org/config.html#confval-html_logo>`_: The name
# of an image file (relative to this directory) to place at the top of the
# sidebar.
##html_logo = None

# `html_favicon <http://sphinx-doc.org/config.html#confval-html_favicon>`_: The
# name of an image file (within the static path) to use as favicon of the docs.
# This file should be a Windows icon file (.ico) being 16x16 or 32x32 pixels
# large.
##html_favicon = None

# `html_static_path <http://sphinx-doc.org/config.html#confval-html_static_path>`_:
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files, so
# a file named ``default.css`` will overwrite the builtin ``default.css``.
# **CodeChat note:** Include the path to CodeChat's static files.
html_static_path = CodeChat.CodeToRest.html_static_path()

# `html_last_updated_fmt <http://sphinx-doc.org/config.html#confval-html_last_updated_fmt>`_:
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
html_last_updated_fmt = "%b, %d, %Y"

# `html_sidebars <http://sphinx-doc.org/config.html#confval-html_sidebars>`_:
# Custom sidebar templates, maps document names to template names.
##html_sidebars = {}

# `html_additional_pages <http://sphinx-doc.org/config.html#confval-html_additional_pages>`_:
# Additional templates that should be rendered to pages, maps page names to
# template names.
##html_additional_pages = {}

# `html_domain_indices <http://sphinx-doc.org/config.html#confval-html_domain_indices>`_:
# If false, no module index is generated.
##html_domain_indices = True

# `html_use_index <http://sphinx-doc.org/config.html#confval-html_use_index>`_:
# If false, no index is generated.
##html_use_index = True

# `html_split_index <http://sphinx-doc.org/config.html#confval-html_split_index>`_:
# If true, the index is split into individual pages for each letter.
##html_split_index = False

# `html_copy_source <http://sphinx-doc.org/config.html#confval-html_copy_source>`_:
# If true, the reST sources are included in the HTML build as _sources/name.
html_copy_source = True

# `html_show_sourcelink <http://sphinx-doc.org/config.html#confval-html_show_sourcelink>`_:
# If true, links to the reST sources are added to the pages.
html_show_sourcelink = True

# `html_sourcelink_suffix <http://sphinx-doc.org/config.html#confval-html_sourcelink_suffix>`_:
# Suffix to be appended to source links (see html_show_sourcelink), unless they
# have this suffix already.
html_sourcelink_suffix = ""

# `html_show_sphinx <http://sphinx-doc.org/config.html#confval-html_show_sphinx>`_:
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
##html_show_sphinx = True

# `html_show_copyright <http://sphinx-doc.org/config.html#confval-html_show_copyright>`_:
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
##html_show_copyright = True

# `html_use_opensearch <http://sphinx-doc.org/config.html#confval-html_use_opensearch>`_:
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it.  The value of this option must be the
# base URL from which the finished HTML is served.
##html_use_opensearch = ''

# `html_file_suffix <http://sphinx-doc.org/config.html#confval-html_file_suffix>`_:
# This is the file name suffix for HTML files (e.g. ".xhtml").
##html_file_suffix = None


# `Intersphinx <https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html>`_
# =======================================================================================
base_git_dir = "C:/Users/bjones/Documents/git"
# `intersphinx_mapping <https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#confval-intersphinx_mapping>`_:
# This config value contains the locations and names of other projects that should be linked to in this documentation.
intersphinx_mapping = {
    "RunestoneComponents": (
        "https://runestonecomponents.readthedocs.io/en/latest/",
        (
            None,
            # An optional local file location -- useful when updating both Sphinx builds before the updates are pushed to the server.
            f"{base_git_dir}/RunestoneComponents/build/RunestoneComponents/objects.inv",
        ),
    ),
    "RunestoneServer": (
        "https://runestoneserver.readthedocs.io/en/latest/",
        (
            None,
            f"{base_git_dir}/web2py/applications/runestone/_build/objects.inv",
        ),
    ),
}


# Exclude empty files matching the given glob from the build.
def exclude_empty_files(
    # The Sphinx application object.
    app_: Sphinx,
    # A `glob pattern <https://docs.python.org/3/library/pathlib.html#pathlib.Path.glob>`_ specifying which files should be excluded if they are empty.
    pattern: str,
):
    # This returns a function which will be called by the `config-inited`_ event.
    def excluder(app: Sphinx, config: Config):
        # The path must start in the `srcdir <https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.srcdir>`_.
        root_path = Path(app.srcdir)
        # This is slightly inefficient, since it doesn't use the existing excludes to avoid searching already-excluded values.
        app.config.exclude_patterns += [  # type: ignore
            # Paths must be relative to the srcdir.
            x.relative_to(root_path).as_posix()
            for x in root_path.glob(pattern)
            if x.stat().st_size == 0
        ]

    # Connect this to the `config-inited <https://www.sphinx-doc.org/en/master/extdev/appapi.html#event-config-inited>`_ Sphinx event.
    app_.connect("config-inited", excluder)


def setup(app):
    # Exclude all empty Python files, since these add no value. (Typically, this will be ``__init__.py``.)
    exclude_empty_files(app, "**/*.py")
    return {"parallel_read_safe": True}
